<template>
  <g class="edge-path" 
    @mouseover="hover = true"
    @mouseleave="handleMouseLeave"
  >
    <!-- 圆形markStart -->
    <!-- <circle :cx="props.sourceX" :cy="props.sourceY" r="4" fill="#29a3ff" /> -->
    <!-- path -->
    <path class="line" :marker-end="markerEnd" :d="path[0]" fill="none" :stroke="hover?'#37d0ff' :selected ? '#f90':'#4d53e8'" :stroke-width="selected? 4.2:3">
      <EdgeLabelRenderer>
        <el-popover :width="420" trigger="click"  ref="popRef">
          <template #reference>
            <div
              @mouseover="hover = true"
              @mouseleave="handleMouseLeave"
              v-show="hover||selected"
              class="edge-edit"
              :style="{
                transform: `translate(-80%, -80%) translate(${path[1]}px,${path[2]}px)`,
              }"
            >
              <Icon type="md-add-circle" color="#37d0ff" size="24" @click="isClickAdd=true" />
            </div>
        </template>
        <NodesPanelModule @node-click="handleAddNodes" @hide="handleHidePanel" />
      </el-popover>

      </EdgeLabelRenderer>
    </path>
    <!-- 箭头markEnd -->
    <path
      class="mark"
      :transform="transform"
      :d="`M ${targetX} ${targetY + 2} L ${targetX - 5} ${targetY - 10} L ${
        targetX + 5
      } ${targetY - 10} Z`"
      :fill="hover?'#37d0ff' :selected ? '#f90':'#4d53e8'"
      stroke="none"
    />
  </g>

</template>

<script setup>
import { getBezierPath, EdgeLabelRenderer, useVueFlow  } from '@vue-flow/core';
import { computed, ref } from 'vue';
import { createNode, editEdges } from '@/api/modules/flow.js';
import NodesPanelModule from './nodes-panel.vue'
import { flowStore } from '@/store/flow';


const NODE_DEFAULT_WIDTH = 350;
const props = defineProps({
  id: {
    type: String,
    required: true,
  },
  source: {
    type: String,
  },
  target: {
    type: String,
  },
  sourceX: {
    type: Number,
    required: true,
  },
  sourceY: {
    type: Number,
    required: true,
  },
  targetX: {
    type: Number,
    required: true,
  },
  targetY: {
    type: Number,
    required: true,
  },
  sourcePosition: {
    type: String,
    required: true,
  },
  targetPosition: {
    type: String,
    required: true,
  },
  sourceNode: {
    type: Object,
    required: true,
  },
  targetNode: {
    type: Object,
    required: true,
  },
  data: {
    type: Object,
    required: false,
    default: () => ({ text: '' }),
  },
  markerEnd: {
    type: String,
    required: false,
  },
  style: {
    type: Object,
    required: false,
  },
  selected: {
    type: Boolean,
    default: false
  },
  serviceaiid: {
    type: String,
    default: ''
  },
  index: {
    type: Number,
    default: 0
  }
});

const hover = ref(false);
const isClickAdd = ref(false);

const emit = defineEmits(['addNode', ]);
const { getDataobj } = flowStore();

const { onNodeDrag, onMove, addNodes, nodes, updateNodeData, addEdges, removeEdges, findNode, } = useVueFlow();
const popRef = ref(null)
onMove(() => {
  if(props.selected) {
    popRef.value?.hide();
  }
  if (hover.value) {
    hover.value = false;
    isClickAdd.value = false;
  }
})
onNodeDrag(() => {
  if(props.selected) {
    popRef.value?.hide();
  }
  if (hover.value) {
    hover.value = false;
    isClickAdd.value = false;
  }
})
const handleHidePanel = () => {
  popRef.value?.hide();
}
const handleMouseLeave = () => {
  if(isClickAdd.value) return;
  hover.value = false;
}

const handleAddNodes = async (nodeInfo, flowserviceid=undefined, plugin) => {
  const { sourceNode, source, target, id: edgeId , targetNode } = props;
  const nodeid = nodeInfo.id;

  try {
    const positionX = sourceNode.dimensions.width + sourceNode.position.x;
    const { data } = await createNode({data: {serviceaiid: props.serviceaiid, nodeid,flowserviceid, x: positionX + 100, y: sourceNode.position.y}})
    // 新节点
    const newNode = {
      id: data.id,
      position: { x: positionX + 100, y: sourceNode.position.y },
      type: data.nodecode,
      label: data.nodename,
      data: {
        ...data,
        ...plugin
      }
    }
    // 调整原目标节点的位置
    changeNodePosition(targetNode)
    // 新增节点
    addNodes([newNode])
     // 移除原先的连接线
    removeEdges(edgeId)
    // 将三个节点连一起（来源节点->新节点->目标节点）
    handleAddEdges([
      {source: source, target: newNode.id, id: `${source}->${newNode.id}`, type:'custom' },
      {source: newNode.id, target: target, id: `${newNode.id}->${target}`, type:'custom'},
    ])
  }finally {
    popRef.value?.hide();
    hover.value = false;
    isClickAdd.value = false;
  }
}

const handleAddEdges = async(edges) => {
  edges.forEach(async edge => {
    const { source, target, sourceHandle } = edge;

    const node = getDataobj()[source];
    const selectionlist = node?.selectionlist || [];
    const newNode = {
      sourceid: source,
      targetid: target,
      name: `${source}->${target}->${sourceHandle || ''}`
    }
    const isIncludes = selectionlist.findIndex(item => item.name == newNode.name);
    console.log(isIncludes)
    if (isIncludes >= 0) return;
    selectionlist.push(newNode)
    try {
      await editEdges({ data:{ id: source, nodecode: node?.nodecode, selectionlist}});
      updateNodeData(source, {selectionlist})
      addEdges({ ...edge });
    }finally{}
  })
}

function changeNodePosition(targetNode) {
  const targetNodeInfo = findNode(targetNode.id);
  targetNodeInfo.position = {
    x: targetNode.position.x + 100 + NODE_DEFAULT_WIDTH,
    y: targetNode.position.y
  }
}


const path = computed(() => getBezierPath({ ...props, curvature: 0.5 }));
const transform = computed(() => {
  return getArrowTransform(props);
});

function getArrowTransform(props) {
  const { targetPosition } = props;
  if (targetPosition === 'top') {
    return `rotate(0 ${props.targetX} ${props.targetY})`;
  }
  if (targetPosition === 'bottom') {
    return `rotate(180 ${props.targetX} ${props.targetY})`;
  }
  if (targetPosition === 'left') {
    return `rotate(-90 ${props.targetX} ${props.targetY})`;
  }
  if (targetPosition === 'right') {
    return `rotate(90 ${props.targetX} ${props.targetY})`;
  }
}
</script>
<script >
export default {
  name: 'CustomEdge',
};
</script>
<style lang="scss">
.edge-edit{
  width: 24px;
  height: 24px;
  line-height: 24px;
  border-radius: 50%;
  background: #fff;
  pointer-events: all;
  position: absolute;
  transition: all .4s ease-in;
  cursor: pointer;
}
.edge-path {
  width: 40px;
  background: transparent;
}
.edge-edit:hover {
  opacity: 1;
}
.vue-flow__edges:hover {
  .line {
    stroke: #37d0ff;
  }
  & ~ .edge-edit {
    opacity: 1;
  }
  .mark {
    fill: #37d0ff;
  }
  
}
</style>